//websocket
const tio = {}
tio.ws = {};

/**
 * {
	 ws_protocol wss or ws ,
	 ip,
	 port,
	 paramStr,加在ws url后面的请求参数，形如：name=张三&id=12
	 heartbeatTimeout,心跳时间 单位：毫秒
	 reconnInterval,重连间隔时间 单位：毫秒
	 binaryType 'blob' or 'arraybuffer';//arraybuffer是字节
	 handler 处理器
 }
 */
tio.ws = function({
	ws_protocol = 'ws',
	ip = '127.0.0.1',
	port = '9326',
	heartbeatTimeout = 5000,
	reconnInterval = 1000,
	binaryType = 'blob',
	paramStr,
	handler
}) {
	this.ip = ip
	this.port = port
	this.url = ws_protocol + '://' + ip + ':' + port
	this.binaryType = binaryType

	if (paramStr) {
		this.url = addUrlParam(this.url, paramStr)
		this.reconnUrl = this.url + "&"
	} else {
		this.reconnUrl = this.url + "?"
	}
	this.reconnUrl += "reconnect=true";

	this.handler = handler
	this.heartbeatTimeout = heartbeatTimeout
	this.reconnInterval = reconnInterval

	this.lastInteractionTime = function() {
		if (arguments.length == 1) {
			this.lastInteractionTimeValue = arguments[0]
		}
		return this.lastInteractionTimeValue
	}

	this.heartbeatSendInterval = heartbeatTimeout / 2

	this.connect = function(isReconnect) {
		var _url = this.url;
		if (isReconnect) {
			_url = this.reconnUrl;
		}
		try {
			var ws = new WebSocket(_url);
			this.ws = ws
		} catch (err) {
			console.log("错误", err)
		}

		ws.binaryType = this.binaryType; // 'arraybuffer'; // 'blob' or 'arraybuffer';//arraybuffer是字节
		var self = this
		ws.onopen = function(event) {
			self.handler.onopen.call(self.handler, event, ws)
			self.lastInteractionTime(new Date().getTime())
			self.pingIntervalId = setInterval(function() {
				self.ping(self)
			}, self.heartbeatSendInterval)
		}
		ws.onmessage = function(event) {
			if (event.data) {
				var data = JSON.parse(event.data)
				console.log(data.code);
				if (data.code != 200) {
					self.handler.onmessage.call(self.handler, data, ws)
				}
				if (data.code == 401) {
					clearInterval(self.pingIntervalId)
				}
			}
			self.lastInteractionTime(new Date().getTime())
		}
		ws.onclose = function(event) {
			clearInterval(self.pingIntervalId) // clear send heartbeat task

			try {
				self.handler.onclose.call(self.handler, event, ws)
			} catch (error) {}

			//self.reconn(event)
		}
		ws.onerror = function(event) {
			clearInterval(self.pingIntervalId)
			self.handler.onerror.call(self.handler, event, ws)
		}

		return ws
	}

	this.reconn = function(event) {
		var self = this
		setTimeout(function() {
			var ws = self.connect(true)
			self.ws = ws
		}, self.reconnInterval)
	}

	this.ping = function() {
		var iv = new Date().getTime() - this.lastInteractionTime(); // 已经多久没发消息了
		// 单位：秒
		if ((this.heartbeatSendInterval + iv) >= this.heartbeatTimeout) {
			this.handler.ping(this.ws)
		}
	};

	this.send = function(data) {
		this.ws.send(data);
	};
}

var addUrlParam = function(url = '', params = {}) {
	if (url && JSON.stringify(params) != "{}") {
		var paramArray = [];
		Object.keys(params).forEach(function(key) {
			var param = key + '=' + params[key]
			paramArray.push(param)
		});
		var url2 = encodeURI(url + '?' + paramArray.join('&'));
		var enurl = encodeURI(url2);
		return enurl
	} else {
		return url;
	}
}

export default tio
